from rest_framework import serializers
from django.contrib.auth.models import User
from .models import (
    AnsibleConfig, AnsibleInventory, AnsibleCredential,
    AnsiblePlaybook, AnsibleJob, AnsibleGlobalSetting
)


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'first_name', 'last_name']


class AnsibleConfigSerializer(serializers.ModelSerializer):
    created_by = UserSerializer(read_only=True)
    health_status_display = serializers.CharField(source='get_health_status_display', read_only=True)

    class Meta:
        model = AnsibleConfig
        fields = [
            'id', 'name', 'description', 'host', 'port', 'username',
            'auth_type', 'password', 'private_key', 'ansible_config_path',
            'inventory_path', 'is_active', 'is_default', 'last_check_time',
            'health_status', 'health_status_display', 'health_message',
            'created_at', 'updated_at', 'created_by'
        ]
        extra_kwargs = {
            'password': {'write_only': True},
            'private_key': {'write_only': True},
        }

    def create(self, validated_data):
        validated_data['created_by'] = self.context['request'].user
        # 确保私钥格式正确（以换行符结尾）
        if 'private_key' in validated_data and validated_data['private_key']:
            private_key = validated_data['private_key']
            if not private_key.endswith('\n'):
                validated_data['private_key'] = private_key + '\n'
        return super().create(validated_data)

    def update(self, instance, validated_data):
        # 确保私钥格式正确（以换行符结尾）
        if 'private_key' in validated_data and validated_data['private_key']:
            private_key = validated_data['private_key']
            if not private_key.endswith('\n'):
                validated_data['private_key'] = private_key + '\n'
        return super().update(instance, validated_data)


class AnsibleInventorySerializer(serializers.ModelSerializer):
    config_name = serializers.CharField(source='config.name', read_only=True)

    class Meta:
        model = AnsibleInventory
        fields = [
            'id', 'config', 'config_name', 'name', 'content', 'file_path',
            'parsed_data', 'hosts_count', 'groups_count', 'is_active',
            'last_sync_time', 'created_at', 'updated_at'
        ]


class AnsibleCredentialSerializer(serializers.ModelSerializer):
    created_by = UserSerializer(read_only=True)
    credential_type_display = serializers.CharField(source='get_credential_type_display', read_only=True)

    class Meta:
        model = AnsibleCredential
        fields = [
            'id', 'name', 'description', 'credential_type', 'credential_type_display',
            'username', 'password', 'private_key', 'public_key',
            'access_key_id', 'secret_access_key', 'vault_password',
            'is_active', 'last_used', 'created_at', 'updated_at', 'created_by'
        ]
        extra_kwargs = {
            'password': {'write_only': True},
            'private_key': {'write_only': True},
            'secret_access_key': {'write_only': True},
            'vault_password': {'write_only': True},
        }

    def create(self, validated_data):
        validated_data['created_by'] = self.context['request'].user
        return super().create(validated_data)


class AnsiblePlaybookSerializer(serializers.ModelSerializer):
    created_by = UserSerializer(read_only=True)
    config_name = serializers.CharField(source='config.name', read_only=True)

    class Meta:
        model = AnsiblePlaybook
        fields = [
            'id', 'name', 'description', 'content', 'file_path',
            'config', 'config_name', 'tags', 'variables', 'is_active',
            'created_at', 'updated_at', 'created_by'
        ]

    def create(self, validated_data):
        validated_data['created_by'] = self.context['request'].user
        return super().create(validated_data)


class AnsibleJobSerializer(serializers.ModelSerializer):
    created_by = UserSerializer(read_only=True)
    config_name = serializers.CharField(source='config.name', read_only=True)
    playbook_name = serializers.CharField(source='playbook.name', read_only=True)
    credential_name = serializers.CharField(source='credential.name', read_only=True)
    job_type_display = serializers.CharField(source='get_job_type_display', read_only=True)
    status_display = serializers.CharField(source='get_status_display', read_only=True)

    class Meta:
        model = AnsibleJob
        fields = [
            'id', 'name', 'job_type', 'job_type_display', 'status', 'status_display',
            'config', 'config_name', 'playbook', 'playbook_name',
            'credential', 'credential_name', 'inventory', 'module_name',
            'module_args', 'extra_vars', 'tags', 'limit', 'result',
            'stdout', 'stderr', 'start_time', 'end_time', 'duration',
            'created_at', 'created_by'
        ]

    def create(self, validated_data):
        validated_data['created_by'] = self.context['request'].user
        return super().create(validated_data)


class AnsibleGlobalSettingSerializer(serializers.ModelSerializer):
    setting_type_display = serializers.CharField(source='get_setting_type_display', read_only=True)
    typed_value = serializers.SerializerMethodField()

    class Meta:
        model = AnsibleGlobalSetting
        fields = [
            'id', 'key', 'value', 'typed_value', 'description',
            'setting_type', 'setting_type_display', 'is_editable',
            'created_at', 'updated_at'
        ]

    def get_typed_value(self, obj):
        return obj.get_typed_value()


# 简化的序列化器用于列表显示
class AnsibleConfigListSerializer(serializers.ModelSerializer):
    class Meta:
        model = AnsibleConfig
        fields = [
            'id', 'name', 'description', 'host', 'port', 'inventory_path',
            'is_active', 'is_default', 'health_status', 'last_check_time'
        ]


class AnsibleInventoryListSerializer(serializers.ModelSerializer):
    config_name = serializers.CharField(source='config.name', read_only=True)

    class Meta:
        model = AnsibleInventory
        fields = [
            'id', 'name', 'config_name', 'hosts_count', 'groups_count',
            'is_active', 'last_sync_time'
        ]


class AnsibleCredentialListSerializer(serializers.ModelSerializer):
    credential_type_display = serializers.CharField(source='get_credential_type_display', read_only=True)

    class Meta:
        model = AnsibleCredential
        fields = [
            'id', 'name', 'credential_type', 'credential_type_display',
            'username', 'is_active', 'last_used', 'created_at'
        ]


class AnsibleJobListSerializer(serializers.ModelSerializer):
    created_by = UserSerializer(read_only=True)
    config_name = serializers.CharField(source='config.name', read_only=True)
    job_type_display = serializers.CharField(source='get_job_type_display', read_only=True)
    status_display = serializers.CharField(source='get_status_display', read_only=True)

    class Meta:
        model = AnsibleJob
        fields = [
            'id', 'name', 'job_type', 'job_type_display', 'status', 'status_display',
            'config_name', 'start_time', 'end_time', 'duration', 'created_at', 'created_by'
        ]
